#include "financialwidget.h"
#include "ui_financialwidget.h"

#include <QVboxLayout>
#include <QHboxLayout>
#include <QPushButton>
#include <QTableView>
#include <QLabel>
#include <QComboBox>
#include <QDateEdit>
#include <QDate>
#include <QDateTime>
#include <QSqlQuery>
#include <QSqlTableModel>
#include <QHeaderView>
#include <QDialog>
#include <QFormLayout>
#include <QLineEdit>
#include <QDialogButtonBox>
#include <QDebug>
#include <QMessageBox>
#include <QSqlError>
#include <QPieSeries>
#include <QLineSeries>
#include <QDateTimeAxis>
#include <QValueAxis>
#include <QtCharts/QChartView>
#include <cmath>

FinancialWidget::FinancialWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::FinancialWidget)
{
    ui->setupUi(this);
    setupUI();
    populateStudentComboBox();
}

FinancialWidget::~FinancialWidget()
{
    delete ui;
}

void FinancialWidget::setupUI(void)
{
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    QHBoxLayout *topLayout = new QHBoxLayout();
    QHBoxLayout *middleLayout = new QHBoxLayout();

    chartView = new  QtCharts::QChartView();
    mainLayout->addLayout(topLayout);
    mainLayout->addLayout(middleLayout, 60);
    mainLayout->addWidget(chartView, 40);
    //==========顶部筛选条件与按钮布局
    topLayout->addWidget(new QLabel("学生姓名", this));
    studentComboBox = new QComboBox(this);
    topLayout->addWidget(studentComboBox);

    topLayout->addWidget(new QLabel("起始日期", this));
    //当前日期往前推一个月
    startDateEdit = new QDateEdit(QDate::currentDate().addMonths(-1), this);
    //启动日历弹出功能
    startDateEdit->setCalendarPopup(true);
    topLayout->addWidget(startDateEdit);

    topLayout->addWidget(new QLabel("结束日期", this));
    endDateEdit = new QDateEdit(QDate::currentDate(), this);
    endDateEdit->setCalendarPopup(true);
    topLayout->addWidget(endDateEdit);

    addButton = new QPushButton("添加");
    deleteButton = new QPushButton("删除");
    editButton = new QPushButton("修改");
    topLayout->addWidget(addButton);
    topLayout->addWidget(deleteButton);
    topLayout->addWidget(editButton);
    topLayout->addStretch();

    //主内容布局
    tableWidget = new QTableWidget();
    tableWidget->setFixedWidth(550);
    //对所有项不可编辑
    tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    //隔行颜色不同
    tableWidget->setAlternatingRowColors(true);

    QStringList header = QStringList() << "ID" << "学生姓名" << "缴费日期" << "金额" << "支付类型" << "备注";
    //设置列数
    tableWidget->setColumnCount(header.size());
    //设置表头
    tableWidget->setHorizontalHeaderLabels(header);
    //隐藏ID列
    tableWidget->setColumnHidden(0, true);
    middleLayout->addWidget(tableWidget);

    pieChartView = new QtCharts::QChartView();
    middleLayout->addWidget(pieChartView);
    //启用抗锯齿
    chartView->setRenderHint(QPainter::Antialiasing);
    chartView->setMinimumHeight(200);

    connect(addButton, &QPushButton::clicked, this, &FinancialWidget::addRecord);
    connect(deleteButton, &QPushButton::clicked, this, &FinancialWidget::deleteRecord);
    connect(editButton, &QPushButton::clicked, this, &FinancialWidget::editRecord);
    connect(studentComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &FinancialWidget::loadFinancialRecords);
    connect(startDateEdit, &QDateEdit::dateChanged, this, &FinancialWidget::loadFinancialRecords);
    connect(endDateEdit, &QDateEdit::dateChanged, this, &FinancialWidget::loadFinancialRecords);
}

void FinancialWidget::loadFinancialRecords(void)
{
    //清空所有行
    tableWidget->setRowCount(0);

    //studentId有可能为-1，如果为-1，则查询所有学生
    QString studentId = studentComboBox->currentData().toString();
    QDate startDate = startDateEdit->date();
    QDate endDate = endDateEdit->date();

    //studentId == "-1" 则查询所有学生
    /*
     "FROM financialRecords fr JOIN studentInfo s ON fr.student_id = s.id " 这个是通过id将两个表合并
     */
    QString queryStr = QString(
        "SELECT fr.id, s.name, fr.payment_date, fr.amount, fr.payment_type, fr.notes "
        "FROM financialRecords fr "
        "JOIN studentInfo s ON fr.student_id = s.id "
        "WHERE fr.payment_date BETWEEN '%1' AND '%2' %3"
    ).arg(startDate.toString("yyyy-MM-dd"), endDate.toString("yyyy-MM-dd"), studentId != "-1" ? QString("AND fr.student_id = '%1'").arg(studentId) : "");

    QSqlQuery query(queryStr);
    qDebug() << "query count:" << query.size() << "queryStr:" << queryStr;
    while (query.next()) //查看是否有数据
    {
        int row = tableWidget->rowCount();
        tableWidget->insertRow(row);

        for (int col = 0; col < 6; ++col) {
            QTableWidgetItem *item = new QTableWidgetItem(query.value(col).toString());
            item->setTextAlignment(Qt::AlignCenter);
            tableWidget->setItem(row, col, item);
        }
    }

    tableWidget->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter);
    updateChart();        //更新下方折线图
    updatePieChart();     //更新右侧饼图
}

void FinancialWidget::addRecord(void)
{
    QDialog dialog(this);
    dialog.setWindowTitle("添加缴费记录");

    QFormLayout form(&dialog);
    //学生的下拉菜单
    QComboBox * studentNameComboBox = new QComboBox(&dialog);
    QSqlQuery query("SELECT id, name FROM studentInfo");
    while (query.next()) {
        QString id = query.value(0).toString();
        QString name = query.value(1).toString();
        studentNameComboBox->addItem(name, QVariant(id));
    }

    QDateEdit * paymentDateEdit = new QDateEdit(&dialog);
    paymentDateEdit->setDate(QDate::currentDate());
    paymentDateEdit->setCalendarPopup(true);

    QLineEdit * amountEdit = new QLineEdit(&dialog);
    QLineEdit * feeTypeEdit = new QLineEdit(&dialog);
    QLineEdit * remarkEdit = new QLineEdit(&dialog);

    form.addRow("学生名称:", studentNameComboBox);
    form.addRow("缴费日期:", paymentDateEdit);
    form.addRow("金额:", amountEdit);
    form.addRow("支付类型:", feeTypeEdit);
    form.addRow("备注:", remarkEdit);

    //添加 确定 取消 按钮
    QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
                               Qt::Horizontal, &dialog);
    buttonBox.button(QDialogButtonBox::Ok)->setText("确定");
    buttonBox.button(QDialogButtonBox::Cancel)->setText("取消");
    form.addRow(&buttonBox);
    QObject::connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
    QObject::connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);

    if (dialog.exec() == QDialog::Accepted) { 
        QString studentId = studentNameComboBox->currentData().toString();
        QString paymentDate = paymentDateEdit->date().toString("yyyy-MM-dd");
        double amount = amountEdit->text().toDouble();
        QString feeType = feeTypeEdit->text();
        QString remark = remarkEdit->text();

        //准备SQL语句
        QSqlQuery query;
        query.prepare("INSERT INTO financialRecords (student_id, payment_date, amount, payment_type, notes) VALUES (:student_id, :payment_date, :amount, :payment_type, :notes)");
        query.bindValue(":student_id", studentId);  //绑定学生ID
        query.bindValue(":payment_date", paymentDate);  //绑定缴费日期
        query.bindValue(":amount", amount);     //绑定缴费金额
        query.bindValue(":payment_type", feeType);  //绑定缴费类型
        query.bindValue(":notes", remark);  //绑定备注
        //执行SQL语句
        if (query.exec()) {
            qDebug() << "Payment record added successfully!";
            loadFinancialRecords();
        } else {
            qDebug() << "Payment record added faile!" << query.lastError().text();
        }
    }
}

void FinancialWidget::deleteRecord(void)
{

}

void FinancialWidget::editRecord(void)
{

}

void FinancialWidget::populateStudentComboBox(void)
{
    studentComboBox->clear();
    studentComboBox->addItem("所有学生", QVariant("-1"));

    QSqlQuery query("SELECT id, name FROM studentInfo");
    while (query.next()) {
        QString id = query.value(0).toString();
        QString name = query.value(1).toString();
        studentComboBox->addItem(name, QVariant(id));
    }
}

void FinancialWidget::updateChart(void)
{
    QDate startDate = startDateEdit->date();
    QDate endDate = endDateEdit->date();

    if (startDate > endDate){
        std::swap(startDate, endDate);
        startDateEdit->setDate(startDate);
        endDateEdit->setDate(endDate);
    }
    QString studentId = studentComboBox->currentData().toString();

    /*将支付日期取名为day, 总金额取名为total*/
    /*查找指定日期范围内*/
    /*按日期分组，并且按天排序*/
    QString queryStr = QString(
        "SELECT DATE(payment_date) AS day, SUM(amount) AS total "
        "FROM financialRecords "
        "WHERE payment_date BETWEEN :startDate AND :endDate "
        "%1 GROUP BY day ORDER BY day")
        .arg(studentId != "-1" ? "AND student_id = :studentId" : "");

    QSqlQuery query;
    query.prepare(queryStr);
    query.bindValue(":startDate", startDate.toString("yyyy-MM-dd"));
    query.bindValue(":endDate", endDate.toString("yyyy-MM-dd"));
    if (studentId != "-1") {
        query.bindValue(":studentId", studentId);
    }
    if (!query.exec())  qCritical() << "[SQL错误]" << query.lastError().text();

    //处理查询数据
    QMap<QString, qreal> dayData;
    qreal maxAmount = 0.0;
    while (query.next()) { 
        QDate day = QDate::fromString(query.value(0).toString(), "yyyy-MM-dd");
        if (!day.isValid()){
            continue;
        }
        qreal amount = query.value(1).toDouble();
        dayData[day.toString("yyyy-MM-dd")] = amount;
        if (amount > maxAmount) {
            maxAmount = amount;
        }
    }
    //创建折线图
    //图表里的数据
    QtCharts::QLineSeries * series = new QtCharts::QLineSeries();
    series->setName("销售额");
    QPen pen(Qt::blue);
    series->setPen(pen);
    QDate currentDate = startDate;
    while (currentDate <= endDate) { 
        qreal value = dayData.value(currentDate.toString("yyyy-MM-dd"), 0.0);
        series->append(QDateTime(currentDate.startOfDay()).toMSecsSinceEpoch(), value);
        currentDate = currentDate.addDays(1);
    }

    //配置坐标轴
    QtCharts::QChart * chart = new QtCharts::QChart();
    chart->addSeries(series);
    QtCharts::QDateTimeAxis * axisX = new QtCharts::QDateTimeAxis();
    axisX->setFormat("yyyy-MM-dd");
    axisX->setTitleText("日期");
    axisX->setRange(QDateTime(startDate.startOfDay()), QDateTime(endDate.startOfDay()));
    chart->addAxis(axisX, Qt::AlignBottom);
    series->attachAxis(axisX);

    QtCharts::QValueAxis * axisY = new QtCharts::QValueAxis();
    axisY->setTitleText("金额(元)");
    axisY->setLabelFormat("%.0f");
    axisY->setTickInterval(10);
    axisY->setRange(0, std::ceil(maxAmount / 10) * 10 + 10);
    chart->addAxis(axisY, Qt::AlignLeft);
    series->attachAxis(axisY);

    //应用图表 - 修改部分
    QtCharts::QChart *oldChart = chartView->chart();
    chartView->setChart(chart);
    chartView->setRenderHint(QPainter::Antialiasing);
    chart->legend()->setVisible(false);
    
    // 在设置新图表后再删除旧图表
    if (oldChart) {
        oldChart->deleteLater();
    }
}

void FinancialWidget::updatePieChart(void)
{
    QString studentId = studentComboBox->currentData().toString();
    QDate startDate = startDateEdit->date();
    QDate endDate = endDateEdit->date();

    /*在指定的日期范围内查询*/
    /*按支付类型进行分类*/
    QString queryStr = QString(
        "SELECT payment_type, SUM(amount) "
        "FROM financialRecords "
        "WHERE payment_date BETWEEN '%1' AND '%2' %3 "
        "GROUP BY payment_type")
        .arg(startDate.toString("yyyy-MM-dd"))
        .arg(endDate.toString("yyyy-MM-dd"))
        .arg(studentId != "-1" ? QString("AND student_id = '%1'").arg(studentId) : "");
    
    QSqlQuery query(queryStr);

    //这个是饼状图的数据
    QtCharts::QPieSeries * series = new QtCharts::QPieSeries();
    qreal totalAmount = 0.0;

    while (query.next()) { 
        QString type = query.value(0).toString();
        qreal value = query.value(1).toDouble();
        totalAmount += value;

        if (value > 0) {
            QString legendLabel = QString("%1 %2元").arg(type).arg(value);
            //单个饼状图数据
            QtCharts::QPieSlice * slice = new QtCharts::QPieSlice(legendLabel, value);
            //隐藏图里的标签，也就是大饼图里不显示标签
            slice->setLabelVisible(false);
            series->append(slice);
        }
    }

    //这个才是饼状图
    QtCharts::QChart * chart = new QtCharts::QChart();
    //添加数据
    chart->addSeries(series);
    chart->setTitle("支付类型分布");

    //图例设置
    chart->legend()->setVisible(true);
    chart->legend()->setAlignment(Qt::AlignBottom);
    chart->legend()->setBackgroundVisible(true);
    chart->legend()->setBrush(QBrush(Qt::white));
    chart->legend()->setLabelColor(Qt::black);
    chart->legend()->setContentsMargins(10, 10, 10, 10);

    series->setPieSize(0.75);

    // 修改部分
    QtCharts::QChart *oldChart = pieChartView->chart();
    pieChartView->setChart(chart);
    pieChartView->repaint();
    
    // 在设置新图表后再删除旧图表
    if (oldChart) {
        oldChart->deleteLater();
    }
}